﻿using Microsoft.EntityFrameworkCore;
using System.Linq.Expressions;
using wwl.Contract.Dtos.Common;
using wwl.Contract.Dtos.Requests.Rbac;
using wwl.Contract.Interfaces.Common;
using wwl.Contract.Interfaces.Rbac;
using wwl.DataAccess.Repositories.Common;
using wwl.Domain.Entities.Rbac;

namespace wwl.DataAccess.Repositories.Rbac
{
  /// <summary>
  /// 用户仓储实现类
  /// </summary>
  public class UserRepository : GenericRepository<User>, IUserRepository
  {
    public UserRepository(IEfWrapper wrapper) : base(wrapper)
    {
    }

    /// <summary>
    /// 根据用户名查询用户
    /// </summary>
    public async Task<User?> GetByUsernameAsync(string username)
    {
      return await QueryNoTracking()
          .FirstOrDefaultAsync(x => x.Username == username && !x.IsDeleted);
    }

    /// <summary>
    /// 检查用户名是否存在
    /// </summary>
    public async Task<bool> ExistsByUsernameAsync(string username, string? excludeId = null)
    {
      var query = QueryNoTracking().Where(x => x.Username == username && !x.IsDeleted);

      if (!string.IsNullOrEmpty(excludeId))
      {
        query = query.Where(x => x.Id != excludeId);
      }

      return await query.AnyAsync();
    }

    /// <summary>
    /// 检查邮箱是否存在
    /// </summary>
    public async Task<bool> ExistsByEmailAsync(string email, string? excludeId = null)
    {
      if (string.IsNullOrEmpty(email))
        return false;

      var query = QueryNoTracking().Where(x => x.Email == email && !x.IsDeleted);

      if (!string.IsNullOrEmpty(excludeId))
      {
        query = query.Where(x => x.Id != excludeId);
      }

      return await query.AnyAsync();
    }

    /// <summary>
    /// 用户分页查询
    /// </summary>
    public async Task<PagedResult<User>> GetPagedAsync(UserPagedRequest request)
    {
      Expression<Func<User, bool>>? filter = null;

      if (!string.IsNullOrWhiteSpace(request.Username) ||
          !string.IsNullOrWhiteSpace(request.FullName) ||
          !string.IsNullOrWhiteSpace(request.Email) ||
          !string.IsNullOrWhiteSpace(request.Status) ||
          !string.IsNullOrWhiteSpace(request.TenantId))
      {
        filter = x =>
            (string.IsNullOrWhiteSpace(request.Username) || x.Username.Contains(request.Username)) &&
            (string.IsNullOrWhiteSpace(request.FullName) || x.FullName.Contains(request.FullName)) &&
            (string.IsNullOrWhiteSpace(request.Email) || (x.Email != null && x.Email.Contains(request.Email))) &&
            (string.IsNullOrWhiteSpace(request.Status) || x.Status.ToString() == request.Status) &&
            (string.IsNullOrWhiteSpace(request.TenantId) || x.TenantId == request.TenantId);
      }

      return await GetPagedAsync(request, filter);
    }
  }
}